﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using RuoVea.ExConfig;
using RuoVea.ExSugar;
using RuoVea.ExUtil;
using RuoVea.OmiApi.Config.Entitys;
using RuoVea.OmiApi.Config.SeedData;
using RuoVea.OmiApi.Config.Service;
using SqlSugar;

namespace RuoVea.OmiApi.Config
{
    /// <summary>
    /// 注入扩展
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 参数配置
        /// </summary>
        /// <param name="services"></param>
        /// <param name="serviceLifetime">Scoped</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiConfigSetup(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            services.Configure<DbInitConfig>(AppSettings.Configuration.GetSection("DbInitConfig"));
            return DI(services, null, serviceLifetime);
        }

        /// <summary>
        /// 参数配置
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="serviceLifetime">Scoped</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiConfigSetup(this IServiceCollection services, IConfiguration config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (config == null) throw new ArgumentNullException(nameof(config));
            services.Configure<DbInitConfig>(config);
            DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
            return DI(services, dbInitConfig, serviceLifetime);
        }

        /// <summary>
        /// 参数配置
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config"></param>
        /// <param name="serviceLifetime">Scoped</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IServiceCollection AddOmiConfigSetup(this IServiceCollection services, Action<DbInitConfig> config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            if (config == null) throw new ArgumentNullException(nameof(config));
            services.Configure(config);
            DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
            return DI(services, dbInitConfig, serviceLifetime);
        }

        #region DI
        private static IServiceCollection DI(IServiceCollection services, DbInitConfig dbInitConfig, ServiceLifetime serviceLifetime)
        {
            if (!services.Any(x => x.ServiceType == typeof(SysConfigService)))
            { 
                switch (serviceLifetime)
                {
                    case ServiceLifetime.Scoped:
                        services.AddScoped<SysConfigService>();
                        break;
                    case ServiceLifetime.Singleton:
                        services.AddSingleton<SysConfigService>();
                        break;
                    case ServiceLifetime.Transient:
                        services.AddTransient<SysConfigService>();
                        break;
                }
            }
            return services;
        }
        #endregion

        /// <summary>
        /// 参数配置接口 - 初始化数据库/初始化种子数据
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddConfigInitSetup(this IServiceCollection services)
        {
            Task.Run(() =>
            {
                DbInitConfig config = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
                var _thisRepository = services.BuildServiceProvider().GetRequiredService<ISqlSugarClient>();
                if (config.InitTable && _thisRepository != null)
                {
                    if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysConfig), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_config", false))
                    {
                    }
                    else
                    {
                        _thisRepository.CodeFirst.InitTables<SysConfig>();
                        if (config.InitSeedData)
                            _thisRepository.Storageable(new SysConfigSeedData().HasData().ToList()).ToStorage().AsInsertable.ExecuteCommand();

                    }
                }
            });
            return services;
        }
    }
}
